package fr.nts.framework.core.task.tool;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

import fr.nts.framework.core.task.SimpleTask;

/**
 * Redéfini {@link Executors} spécifique au framework NTS.
 * 
 * @author sco
 * @version 1.0.0
 */
public class SimpleTaskExecutors extends ThreadPoolExecutor{
	
	private final static Logger log = LoggerFactory.getLogger(SimpleTaskExecutors.class);
	
	/**
	 * Construit une nouvelle instance de {@link SimpleTaskExecutors}.
	 * 
	 * @param nbTask Le nombre de thread max
	 */
	public SimpleTaskExecutors(int nbTask){
		super(nbTask, 
		      nbTask,
			  0L, 
		      TimeUnit.MILLISECONDS,
		      new LinkedBlockingQueue<Runnable>());
	}
   
	
	/**
	 * Lance une nouvelle tâche de type {@link SimpleTask}. Cette tâche ne gère pas d'objet en retour
	 * 
	 * @param task La tâche à lancer
	 */
	public <T extends Object> void addSilentTask(SimpleTask<T> task){
		log.debug("On lance la tâche sans retour: {}", task);
		
		super.submit(task);
	}
	
	
	/**
	 * Lance une nouvelle tâche de type {@link SimpleTask}
	 * 
	 * @param task La tâche à lancer
	 * @return Le résultat en cours de la tâche
	 */
	public <T extends Object> Future<Boolean> addTask(SimpleTask<T> task){
		log.debug("On lance la tâche: {}", task);
		
		Future<Boolean> result = super.submit(task, 
				                              Boolean.TRUE);
		
		return result;
	}
	
	
	/**
	 * Arrete toutes les tâches
	 * 
	 * @return La liste des tâches non arrêtées.
	 */
	public List<SimpleTask<?>> shutdownPool(){
		List<Runnable> listOfStyleRunnableTask = super.shutdownNow();
		
		List<SimpleTask<?>> result = Lists.newArrayList();
		for(Runnable aTask: listOfStyleRunnableTask){
			result.add((SimpleTask<?>)aTask);
		}
		
		return result;
	}
}